#ifndef __BLDC_H
#define __BLDC_H

#include "stm32g4xx_hal.h"



// 电机输出使能引脚
#define MOTOR_OUTPUT_ENABLE_PIN GPIO_PIN_13
#define MOTOR_OUTPUT_ENABLE_PORT GPIOC

// 电机下桥臂引脚定义
#define MOTOR_U_LOW_PIN GPIO_PIN_13
#define MOTOR_U_LOW_PORT GPIOB
#define MOTOR_V_LOW_PIN GPIO_PIN_14
#define MOTOR_V_LOW_PORT GPIOB
#define MOTOR_W_LOW_PIN GPIO_PIN_15
#define MOTOR_W_LOW_PORT GPIOB

// 电机上桥臂引脚定义
#define MOTOR_U_UP_PIN GPIO_PIN_8
#define MOTOR_U_UP_PORT GPIOA
#define MOTOR_V_UP_PIN GPIO_PIN_9
#define MOTOR_V_UP_PORT GPIOA
#define MOTOR_W_UP_PIN GPIO_PIN_10
#define MOTOR_W_UP_PORT GPIOA


#define PWM_FREQUENCY_HZ 20000  // PWM频率 20kHz
#define TIMER_REPETITION_COUNT 1 // 在20khz下，每个周期产生一次中断，也就是50us产生一次中断
#define DEAD_TIME_NS 800       // 死区时间 800ns

/*
bldc 为2对极（四个极），转动一圈，同一hall状态变化4次为一圈，每次变化消耗时间为n个周期，一个周期为
1次timer 中断时间，一次timer 中断时间为 TIMER_REPETITION_COUNT/PWM_FREQUENCY_HZ 目前是50us
所以转动一圈的时间为4*n*50us, 所以 一秒转动的圈数为 1s/(4*n*50us),一分钟转动的圈数为 60s/(4*n*50us)
将分数上下都s单位去掉，50us 就是1/20000s 最后得出60*20000/4*n 假设n=1,那么此时机会得到
60*20000/4=300000*/
#define RPM_CALC_NUMERATOR      (uint32_t)(60*(PWM_FREQUENCY_HZ/TIMER_REPETITION_COUNT)/4)




// 获取TIM1时钟频率的宏定义
// TIM1挂在APB2总线上，当前配置APB2预分频器=/1，所以定时器时钟=PCLK2
#define GET_TIM1_CLOCK_FREQ() HAL_RCC_GetPCLK2Freq()

// 动态计算PWM周期值
#define GET_PWM_PERIOD_VALUE() (uint32_t)(GET_TIM1_CLOCK_FREQ() / PWM_FREQUENCY_HZ)

#define CURRENT_OFFSET_CALIBRATION_SAMPLES 1024 // 电流偏置校准采样次数

#define ADC2CURT        (float)(3.3f / 4.096f / 0.12f)  /* ADC采集值 * 3.3/4.096 （mv） = 6 * ( 0.02*I ) */
#define ADC2VBUS        (float)(3.3f * 25 / 4096)       /* ADC采集值 * 3.3/4096 （V）= POWER/(12K+12K+1K)*1K */

#define FirstOrderRC_LPF(Yn_1, Xn, a) Yn_1 = (1 - a) * Yn_1 + a * Xn;  /* Yn:out;Xn:in;a:系数 一阶滤波 */


/***************************************** 电机状态结构体 ***********************************************/
typedef struct {
    __IO uint8_t    run_flag;       /* 运行标志 */
    __IO uint8_t    locked_rotor;   /* 堵转标记 */
    __IO uint8_t    step_sta;       /* 本次霍尔状态 */
    __IO uint8_t    hall_single_sta;/* 单个霍尔状态 */
    __IO uint8_t    hall_sta_edge;  /* 单个霍尔状态跳变 */
    __IO uint8_t    step_last;      /* 上次霍尔状态 */
    __IO uint8_t    dir;            /* 电机旋转方向 */
    __IO int32_t    pos;            /* 电机位置 */
    __IO int32_t    speed;          /* 电机速度 */
    __IO int16_t    current;        /* 电机速度 */
    __IO uint32_t   pwm_duty;       /* 电机占空比 */
    __IO uint32_t   hall_keep_t;    /* 霍尔保持时间 */
    __IO uint32_t   hall_pul_num;   /* 霍尔传感器脉冲数 */
    __IO uint32_t   lock_time;      /* 电机堵转时间 */
    __IO uint32_t   no_single;
    __IO uint32_t   count_j;
    __IO float      current_u;      /* 电机U相电流 */
    __IO float      current_v;      /* 电机V相电流 */
    __IO float      current_w;      /* 电机W相电流 */
    __IO uint16_t   adc_offset_u;   /* ADC offset for phase U */
    __IO uint16_t   adc_offset_v;   /* ADC offset for phase V */
    __IO uint16_t   adc_offset_w;   /* ADC offset for phase W */
    __IO uint8_t    initial_calibration_done; /* 初始校准完成标志 */
} _bldc_obj;


// 外部变量声明
extern _bldc_obj g_bldc_motor1;
extern uint32_t motor_timer_tick;

typedef enum {
    FORWARD_ROTATION = 0, //正转
    REVERSE_ROTATION = 1 //反转
} motor_direction_t;

typedef enum {
    MOTOR_STOP = 0,
    MOTOR_RUN = 1
} motor_status_t;

typedef struct {
    motor_status_t motor_status;//电机状态
    motor_direction_t motor_direction;//电机旋转反向
    uint32_t pwm_duty;//pwm占空数值，不是比例
} bldc_ctrl_t;

// 为了兼容性，也提供一个静态获取函数
static inline uint32_t bldc_get_pwm_period_value(void)
{
    return GET_PWM_PERIOD_VALUE();
}

// 为了兼容性，也提供一个获取时钟频率的函数
static inline uint32_t bldc_get_timer_clock_freq(void)
{
    return GET_TIM1_CLOCK_FREQ();
}

// 电机控制函数指针类型
typedef void (*motor_ctr_t)(void);

// 函数声明
void bldc_init(void);
void bldc_timer_init(void);
void bldc_start(void);
void bldc_set_duty_cycle(uint8_t phase, uint16_t duty);
void bldc_test_motor(void);
void bldc_print_clock_info(void);  // 调试函数：打印时钟信息
void motor_test(void);
void bldc_stop(void);
void bldc_start(void);
void m1_uhvl(void);
void m1_uhwl(void);
void m1_vhul(void);
void m1_vhwl(void);
void m1_whul(void);
void m1_whvl(void);
uint8_t bldc_get_motor_status(void);
void bldc_set_pwm_duty(uint32_t duty);
void bldc_set_motor_direction(motor_direction_t direction);

void bldc_timer_interrupt_callback(void);
void bldc_safe_direction_change(motor_direction_t new_direction);
void motor_zero_vector(void);

void bldc_current_offset_calibration(void);
void bldc_get_phase_currents(volatile float *i_u, volatile float *i_v, volatile float *i_w);
uint8_t bldc_get_motor_direction(void);


#endif
